import os

from django.db import models
from django.conf import settings
from django.contrib.auth.models import User

from utils import nlp
from utils import voicevox


class Lesson(models.Model):
    # 只是一个大概的分类，不需要特别严格，比如一个动漫歌曲，可以分到动漫，也可以分到音乐。
    LESSON_SOURCES = {
        'anime': '动漫',
        'books': '图书',
        'music': '音乐'
    }
    name = models.CharField(max_length=100)
    source = models.CharField(max_length=10, choices=LESSON_SOURCES, default='anime')

    def __str__(self):
        return self.name


class Word(models.Model):
    text = models.CharField(max_length=100, unique=True)
    audio = models.FileField(upload_to='words/', null=True)

    def __str__(self):
        return self.text


class Sentence(models.Model):
    words = models.ManyToManyField(Word, related_name='sentences', blank=True)
    text = models.CharField(max_length=300, unique=True) # 原始的完整句子文本
    lesson = models.ForeignKey(Lesson, on_delete=models.DO_NOTHING, blank=True, null=True)
    audio = models.FileField(upload_to='sentencs/', blank=True, null=True)

    def __str__(self):
        return f'{self.id}「{self.lesson}」：{self.text}'

    def create_question(self):
        s = nlp.Sentence(self.text)
        question, answer, options = s.create_question()
        return question, answer, options

    def create_words(self):
        s = nlp.Sentence(self.text)
        for word in s.words:
            Word.objects.create(text=word.text)

    def create_audio(self):
        """
        Call this method to create audio file for this sentence.
        Normally you don't need to upload audio file, unless the auto-generated audio is incorrect.
        To correct the audio file, you can use admin site to edit the particular sentence.
        """
        vox = voicevox.Audio(self.text)
        root = settings.MEDIA_ROOT
        filename = f'sentences/sentence_{self.id}.wav'
        with open(os.path.join(root, filename), 'wb') as audio_file:
            audio_file.write(vox.get_file())
        self.audio = filename
        self.save()

    @classmethod
    def create_audio_all(cls, override=False):
        for sentence in cls.objects.all():
            if (not sentence.audio and not override) or override:
                sentence.create_audio()


class WordScore(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='word_scores')
    word = models.ForeignKey(Word, on_delete=models.CASCADE, related_name='word_scores')
    score = models.IntegerField(help_text="熟练度从0-100.")  # 假设熟悉度是一个1到10的整数

    class Meta:
        unique_together = ('user', 'word')  # 确保每个用户对每个单词的熟悉度是唯一的

    def __str__(self):
        return f"{self.user} - {self.word} - Level {self.score}"


class SentenceScore(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='sentence_scores')
    sentence = models.ForeignKey(Sentence, on_delete=models.CASCADE, related_name='sentence_scores')
    score = models.IntegerField(help_text="熟练度从0-100.")  # 假设熟悉度是一个1到10的整数

    class Meta:
        unique_together = ('user', 'sentence')  # 确保每个用户对每个单词的熟悉度是唯一的

    def __str__(self):
        return f"{self.user} - {self.sentence} - Level {self.score}"